package com.feicheng.common.wx.pay;

import com.feicheng.common.exception.SystemException;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.*;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;

/**
 * 微信支付工具类
 * 微信整个支付流程统一由微信管理
 * 我们只需要配置好httpClient，每次获取Client发起对应的请求就好了
 */
@Slf4j
@Data
public class WxPayHttpClientFactory {

    private String merchantId; // 商户mid

    private String merchantSerialNo; // 商户证书序列号

    private String merchantPrivateKeyStr; // 商户证书私钥

    private String apiV3Key; // V3秘钥

    /**
     * 微信支付工厂内部建造者
     */
    public static class Builder {
        private String merchantId; // 商户mid

        private String merchantSerialNo; // 商户证书序列号

        private String merchantPrivateKeyStr; // 商户证书私钥

        private String apiV3Key; // V3秘钥

        public Builder(String merchantId) {
            this.merchantId = merchantId;
        }

        public Builder setMerchantSerialNo(String merchantSerialNo) {
            this.merchantSerialNo = merchantSerialNo;
            return this;
        }

        public Builder setMerchantPrivateKeyStr(String merchantPrivateKeyStr) {
            this.merchantPrivateKeyStr = merchantPrivateKeyStr.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "")
                    .replaceAll("\\r\\n", "");
            return this;
        }

        public Builder setApiV3Key(String apiV3Key) {
            this.apiV3Key = apiV3Key;
            return this;
        }

        public WxPayHttpClientFactory build() {
            return new WxPayHttpClientFactory(this);
        }
    }

    private WxPayHttpClientFactory(Builder builder) {
        initFactory(
                builder.merchantId,
                builder.merchantSerialNo,
                builder.merchantPrivateKeyStr,
                builder.apiV3Key);
    }

    /**
     * 初始化工厂类参数
     *
     * @param merchantId       商户id
     * @param merchantSerialNo 商户证书序列号
     * @param apiV3Key         V3秘钥
     */
    private void initFactory(String merchantId, String merchantSerialNo, String merchantPrivateKeyStr, String apiV3Key) {
        this.merchantId = merchantId;
        this.merchantSerialNo = merchantSerialNo;
        this.merchantPrivateKeyStr = merchantPrivateKeyStr;
        this.apiV3Key = apiV3Key;
    }


    /**
     * 获取微信支付httpClient
     *
     * @return httpClient
     */
    public CloseableHttpClient getHttpClient() {
        return initHttpClient();
    }

    /**
     * 初始化客户端
     *
     * @return httpClient
     */
    public CloseableHttpClient initHttpClient() {
        CloseableHttpClient httpClient = null;
        try {
            // 加载商户私钥（merchantPrivateKeyStr：私钥字符串）
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                    new ByteArrayInputStream(merchantPrivateKeyStr.getBytes("utf-8")));

            // 加载平台证书（merchantId：商户号,merchantSerialNo：商户证书序列号,apiV3Key：V3秘钥）
            ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
                    new WechatPay2Credentials(merchantId, new PrivateKeySigner(merchantSerialNo, merchantPrivateKey)),
                    apiV3Key.getBytes(StandardCharsets.UTF_8));

            //httpClient构造器，可以继续通过builder构造其他参数
            WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                    .withMerchant(merchantId, merchantSerialNo, merchantPrivateKey)
//                    .withWechatPay(PemUtil.loadCertificate(new FileInputStream("D:/feicheng/戍码助学/apiclient_cert.p12")));
                    .withValidator(new WechatPay2Validator(verifier));
//                    .withValidator(response -> true);
            // 初始化httpClient
            httpClient = builder.build();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("初始化微信支付httpClient失败！");
            throw new SystemException("初始化微信支付httpClient失败！");
        }
        return httpClient;
    }


}
